// ===============================================
// dio_interceptor
//
// Create by Will on 2020/10/5 4:13 PM
// Copyright @data_food.All rights reserved.
// ===============================================

import 'package:dio/dio.dart';
import 'package:flutter_base/core/entity/respones/base_response.dart';
import 'package:flutter_base/core/exception/api_exception.dart';

import '../core_kit.dart';

class CoreInterceptor extends Interceptor {
  /// 在此处改造请求，统一加入Token
  @override
  Future onRequest(RequestOptions options) async {
    if (await options.isFromBaseUrl()) {
      if (options.headers == null) {
        options.headers = {};
      }

      final headers = options.headers;
      final apiHeaders = await CoreKit.config?.apiHeadersGenerator;
      if (apiHeaders != null) {
        for (final apiHeader in apiHeaders.entries) {
          headers.putIfAbsent(apiHeader.key, () => apiHeader.value);
        }
      }
    }

    return super.onRequest(options);
  }

  @override
  Future onResponse(Response response) async {
    if (await response.request.isFromBaseUrl()) {
      final entity = BaseResponse.tryParse(response.data);

      if (entity != null) {
        if (entity.isSuccess == true) {
          // 抛掉BaseResponse的包装，直接返回result
          response.data = entity.result;
          return response;
        }
        else {
          // 触发异常
          return DioError(
            request: response.request,
            response: response,
            type: DioErrorType.RESPONSE,
            error: CoreKitAPIException(
              entity.code,
              message: entity.message,
            ),
          );
        }
      }
    }

    return super.onResponse(response);
  }

  @override
  Future onError(DioError err) async {
    if (err.type == DioErrorType.RESPONSE &&
        await err.response.request.isFromBaseUrl()) {
      final entity = BaseResponse.tryParse(err.response.data);

      if (entity != null) {
        return DioError(
          request: err.request,
          response: err.response,
          type: DioErrorType.RESPONSE,
          error: CoreKitAPIException(
            entity.code,
            message: entity.message,
          ),
        );
      }
    }

    return super.onError(err);
  }
}




extension RequestOptionsExt on RequestOptions {
  Future<bool> isFromBaseUrl() async {
    final baseUrls = await CoreKit.config?.apiBaseUrlsGetter;
    final test = (baseUrl) => uri.toString().startsWith(baseUrl);
    return baseUrls?.any(test) == true;
  }
}